几种常见的组件导入方式
在 Spring Boot 项目中,如果你在公共模块 @Configuration 配置类,需要在其他模块中使用,通常有以下几种常见的方式,我们进行逐一介绍。
组件扫描(最常用)
1 2 3 4 5 6 7
| @SpringBootApplication @ComponentScan(basePackages = {"com.xxx.common", "com.xxx.admin"}) public class AdminApplication { public static void main(String[] args) { SpringApplication.run(AdminApplication.class, args); } }
|
通过 @Import 导入
在当前模块项目的配置类或启动类上直接导入公共模块的配置类:
1 2 3 4 5 6 7
| @SpringBootApplication @Import({CommonConfig1.class, CommonConfig2.class}) public class AdminApplication { public static void main(String[] args) { SpringApplication.run(AdminApplication.class, args); } }
|
通过 @ImportResource 导入
在当前模块项目的配置类或启动类上直接导入公共模块的配置类:
1 2 3 4 5 6 7
| @SpringBootApplication @ImportResource(value = {"classpath:config1.xml", "classpath:spring/config2.xml"}) public class AdminApplication { public static void main(String[] args) { SpringApplication.run(AdminApplication.class, args); } }
|
利用自动配置
如果公共模块中定义了自动配置类,可以在 META-INF/spring.factories 中注册:
1 2
| org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.xxx.common.config.CommonConfig
|
或者使用 Spring Boot 2.7+ 推荐的 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件:
1
| com.xxx.common.config.CommonConfig
|
手写一个自动配置 starter 的示例
以下这个 Starter 会实现一个简单的短信发送服务,包含自动配置、属性绑定和条件加载。
项目结构
1 2 3 4 5 6 7 8 9 10
| my-sms-spring-boot-starter/ ├── pom.xml └── src/main/java/com/owlias/sms/ ├── SmsProperties.java ├── SmsService.java ├── SmsServiceImpl.java ├── SmsAutoConfiguration.java └── resources/META-INF/ └── spring/ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports
|
项目依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>com.owlias</groupId> <artifactId>my-sms-spring-boot-starter</artifactId> <version>1.0.0</version>
<properties> <java.version>17</java.version> <spring-boot.version>3.5.13</spring-boot.version> </properties>
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> <version>${spring-boot.version}</version> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <version>${spring-boot.version}</version> <optional>true</optional> </dependency>
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.30</version> <optional>true</optional> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.17</version> </dependency> </dependencies> </project>
|
配置属性类
SmsProperties
1 2 3 4 5 6 7 8 9 10
| @Data @ConfigurationProperties(prefix = "sms") public class SmsProperties { private boolean enabled = true; private String provider = "aliyun"; private String apiKey; private String apiSecret; private String signName; private int connectTimeout = 5000; }
|
服务接口和实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| public interface SmsService { boolean send(String phoneNumber, String message); boolean sendVerificationCode(String phoneNumber, String code); }
public class SmsServiceImpl implements SmsService { private static final Logger log = LoggerFactory.getLogger(SmsServiceImpl.class); private final SmsProperties properties;
public SmsServiceImpl(SmsProperties properties) { this.properties = properties; }
@Override public boolean send(String phoneNumber, String message) { log.info("=== 短信发送 ==="); log.info("提供商: {}", properties.getProvider()); log.info("签名: {}", properties.getSignName()); log.info("手机号: {}", phoneNumber); log.info("内容: {}", message); log.info("================");
return true; }
@Override public boolean sendVerificationCode(String phoneNumber, String code) { String message = String.format("您的验证码是:%s,5分钟内有效。", code); return send(phoneNumber, message); } }
|
自动配置类
SmsAutoConfiguration
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @AutoConfiguration @EnableConfigurationProperties(SmsProperties.class) @ConditionalOnClass(SmsService.class) @ConditionalOnProperty(prefix = "sms", name = "enabled", havingValue = "true", matchIfMissing = true) public class SmsAutoConfiguration { private static final Logger log = LoggerFactory.getLogger(SmsAutoConfiguration.class);
private final SmsProperties properties; public SmsAutoConfiguration(SmsProperties properties) { this.properties = properties; log.info("短信服务自动配置已初始化"); }
@Bean @ConditionalOnMissingBean(SmsService.class) public SmsService smsService() { log.info("创建短信服务 Bean,提供商: {}", properties.getProvider()); return new SmsServiceImpl(properties); } }
|
Spring Boot 3.x 注册文件
创建文件:src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
1
| com.owlias.sms.SmsAutoConfiguration
|
在使用方调用
导入上述 sms starter 依赖后,先在 application.yml 声明:
1 2 3 4 5 6 7
| sms: enabled: true provider: aliyun api-key: your-api-key api-secret: your-api-secret sign-name: 腾讯云短信 connect-timeout: 3000
|
在业务代码中使用:
1 2 3 4 5 6 7 8 9 10 11
| @Service public class UserService {
@Autowired private SmsService smsService;
public void register(String phone) { smsService.sendVerificationCode(phone, "123456"); } }
|
禁用 Starter:
或者在启动类排除:
1
| @SpringBootApplication(exclude = SmsAutoConfiguration.class)
|
标题:
Spring Boot Starter 的手写示例